package homework.homework01;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DBUtil {
    private static Connection con = null;
    private static PreparedStatement ps = null;
    private static ResultSet rSet = null;

    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String URL = "jdbc:mysql://localhost:3306/dormitory_management?useSSL=false&serverTimezone=Asia/Shanghai";
    private static final String USER = "root";
    private static final String PWD = "root";

    private DBUtil(){

    }

    public static Connection getCon() throws Exception {
            Class.forName(DRIVER);
            return DriverManager.getConnection(URL,USER,PWD);
    }

    public static void close(){
        try {
            if(rSet != null){
                rSet.close();
            }

            if(ps != null){
                ps.close();
            }

            if(con != null){
                con.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static int excuteUpdate(String sql, Object... parms){
        int result = 0;
        try {
            con = getCon();
            ps =  con.prepareStatement(sql);
            con.setAutoCommit(false); // 开启事物，凡是数据库进行增删改操作则都需要开启事物

            if(parms != null){
                for (int i = 1; i <= parms.length; i++) {
                    ps.setObject(i, parms[i-1]);
                }
            }

            result =   ps.executeUpdate();
            con.commit(); // 若运行成功，则将事物提交

        } catch (Exception e) {
            try {
                con.rollback(); // 运行失败，则将事物回滚，回到之前的数据
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
        close();
        return result;
    }

    public static ResultSet excuteQuery(String sql, Object... parms){
        try {
            con = getCon();
            ps = con.prepareStatement(sql);
            if(parms != null){
                for (int i = 1; i <= parms.length; i++) {
                    ps.setObject(i, parms[i-1]);
                }
            }

            rSet = ps.executeQuery();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return rSet;
    }

    public  static <T> List<T> getDatas(String sql, Class<T> clazz){
        List<T> list = new ArrayList<>();
        ResultSet rSet = excuteQuery(sql);
        Field[] fields = clazz.getDeclaredFields();

        try {
            while(rSet.next()){
                T t = clazz.newInstance();
               String methodName = "";
                for (int i = 0; i < fields.length; i++) {
                   methodName = "set" + fields[i].getName().substring(0,1).toUpperCase() + fields[i].getName().substring(1);
                   clazz.getMethod(methodName, fields[i].getType()).invoke(t, rSet.getObject(fields[i].getName()));
                }
                list.add(t);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            close();
        }

        return list;
    }
}
